using System.Collections.Generic;
using System.Linq;
using Net.Common;
using PEMath;
using UnityEngine;
using UnityEngine.UI;

/****************************************************
// 功能：
// | Talk To [ 聊来改善地区金融服务环境，助力企业发展 ]
// | Copyright (c) 2021-2025 聊来 All rights reserved.
// | Licensed ( <a href="http://www.apache.org/licenses/LICENSE-2.0">聊来</a> )
// | @Author: 贯彻己道的云 <18970881148@qq.com>
// | DateTime: 2025/3/27 15:3:8
*****************************************************/

public partial class PlayerControlWindow : BaseWindow
{
    public Image imgCancelSkill;
    public Image imgTouch;
    public Image imgDirBg;
    public Image imgDirPoint;
    public Transform ArrowRoot;

    public Text txtTime;
    public Text txtBlueKill;
    public Text txtRedKill;
    public Text txtIncome;
    public Text txtFPS;
    public Text txtDelay;
    public Text txtChat;
    public InputField iptChat;
    public Image imgCover;
    public Text txtRevieTime;
    public int maxChatLen;
    public int maxChatCount;
    public float chatShowTime;
    
    
    private Vector2 lastKeyDir = Vector2.zero;
    private Vector2 lastStickDir = Vector2.zero;

    private float pointDis;
    private Vector2 startPosition = Vector2.zero;
    private Vector2 defaultPosition = Vector2.zero;
    
    private int blueTeamKillCount;
    private int redTeamKillCount;
    
    private int battleSecondCount;
    private float battleTimeCounter;

    private float frameTimeCount;
    private int frameCounter;
    
    private List<ChatItem> chatList;

    protected override void InitWindows()
    {
        base.InitWindows();

        BattleController.Instance.playerWindow = this;
        
        SetActive(imgCancelSkill, false);
        chatList = new List<ChatItem>();
        txtChat.text = "";
        iptChat.text = "";
        SetActive(txtChat, false);
        SetActive(iptChat, false);
        SetActive(imgCover, false);
        blueTeamKillCount = 0;
        redTeamKillCount = 0;
        SetText(txtBlueKill, blueTeamKillCount);
        SetText(txtRedKill, redTeamKillCount);
        SetActive(ArrowRoot, false);
        
        // 解决屏幕适配的问题
        pointDis = Screen.height * 1.0f / Constants.SCREEN_STANDARD_HEIGHT * Constants.SCREEN_DP_DIS;
        defaultPosition = imgDirBg.transform.position;
        
        RegisterTouchEvents();
        
        // 加载小地图
        InitMiniMap();
    }

    protected override void ClearWindows()
    {
        base.ClearWindows();
        UnInitMiniMap();
        BattleController.Instance.playerWindow = null;

        if (chatList == null) return;
        chatList.Clear();
        chatList = null;
    }

    private void Update()
    {
        /*var h = Input.GetAxisRaw("Horizontal");
        var v = Input.GetAxisRaw("Vertical");
        var keyDir = new Vector2(h, v);
        if(keyDir != lastKeyDir) {
            if(h != 0 || v != 0) {
                keyDir = keyDir.normalized;
            }
            InputMoveKey(keyDir);
            lastKeyDir = keyDir;
        }*/
        
        UpdateSkillWnd();
        var delta = Time.deltaTime;
        UpdatePing(model.netDelay);
        UpdateChatList(delta);
        UpdateImgInfo(delta);
        UpdateTime(delta);
        UpdateFPS(delta);
    }


    private void InputMoveKey(Vector2 dir)
    {
        if (dir.Equals(lastStickDir)) return;
        Vector3 dirVector3 = new Vector3(dir.x, 0, dir.y);
        dirVector3 = Quaternion.Euler(0, 45, 0) * dirVector3;
        PEVector3 logicDir = PEVector3.zero;
        if(dir != Vector2.zero) {
            isUIInput = true;
            logicDir.x = (PEInt)dirVector3.x;
            logicDir.y = (PEInt)dirVector3.y;
            logicDir.z = (PEInt)dirVector3.z;
        }
        else {
            isUIInput = false;
        }

        var isSend = BattleController.Instance.SendMoveKey(logicDir);
        if(isSend) {
            lastStickDir = dir;
        }
    }


    /// <summary>
    /// 注册摇杆事件
    /// </summary>
    private void RegisterTouchEvents()
    {
        SetActive(ArrowRoot, false);

        OnClickDown(imgTouch.gameObject, data => {
            startPosition = data.position;
            imgDirPoint.color = new Color(1, 1, 1, 1f);
            imgDirBg.transform.position = data.position;
        });
        OnClickUp(imgTouch.gameObject, data => {
            imgDirBg.transform.position = defaultPosition;
            imgDirPoint.color = new Color(1, 1, 1, 0.5f);
            imgDirPoint.transform.localPosition = Vector2.zero;
            SetActive(ArrowRoot, false);

            InputMoveKey(Vector2.zero);
        });
        OnDrag(imgTouch.gameObject, data => {
            var dir = data.position - startPosition;
            var len = dir.magnitude;
            if(len > pointDis) {
                var clampDir = Vector2.ClampMagnitude(dir, pointDis);
                imgDirPoint.transform.position = startPosition + clampDir;
            }
            else {
                imgDirPoint.transform.position = data.position;
            }

            if(dir != Vector2.zero) {
                SetActive(ArrowRoot);
                var angle = Vector2.SignedAngle(new Vector2(1, 0), dir);
                ArrowRoot.localEulerAngles = new Vector3(0, 0, angle);
            }

            InputMoveKey(dir.normalized);
        });
    }

    
    public void EnterCdState(int skillId, int cdTime)
    {
        if (skaItem.CheckSkillId(skillId))
        { 
            skaItem.EnterCdState(cdTime);
        }else if(sk1Item.CheckSkillId(skillId)) {
            sk1Item.EnterCdState(cdTime);
        }
        else if(sk2Item.CheckSkillId(skillId)) {
            sk2Item.EnterCdState(cdTime);
        }
        else if(sk3Item.CheckSkillId(skillId)) {
            sk3Item.EnterCdState(cdTime);
        }
        else {
            Debug.LogError($"skill id{skillId} enter cd error.");
        }
    }
    
    private bool isUIInput = false;
    public bool IsUIInput() {
        return isUIInput;
    }

    public void ShowResult(bool isSuccess)
    {
        StartCoroutine(BattleController.Instance.ShowResult(isSuccess));
    }

    #region BattleInfo


    public void OnChantButton()
    {
        if(iptChat.gameObject.activeSelf) {
            iptChat.gameObject.SetActive(false);

            var chatStr = iptChat.text;
            var selfHero = BattleController.Instance.GetSelfHero();
            var userName = (selfHero as Hero)?.userName;
            var unitId = selfHero.unitData.unitConfig.unitId;
            var heroName = resource.GetUnitConfigData(unitId).unitName;

            if (string.IsNullOrEmpty(chatStr)) return;
            if(chatStr.Length >= maxChatLen) {
                ui.ShowTips("最多发送20个字");
                return;
            }
            chatStr = selfHero.IsTeam(TeamEnum.Blue) ? $"<color=#2B91D1>[全部]{userName}({heroName}):</color>{chatStr}" : $"<color=#C83535>[全部]{userName}({heroName}):</color>{chatStr}";

            // 发送消息
            SendByWebSocket(RequestType.SEND_CHAT, new SendChatRequest()
            {
                roomId = model.roomId,
                msg = chatStr
            });
            iptChat.text = "";
        }
        else {
            iptChat.gameObject.SetActive(true);
        }
    }
    
    public void AddChatMsg(string msg)
    {
        while (chatList.Count > maxChatCount - 1)
        {
            chatList.RemoveAt(0);
        }
        
        chatList.Add(new ChatItem()
        {
            timeCounter = chatShowTime,
            chatMsg = msg
        });
        
        RefreshChatUI();
    }
    
    private void UpdateChatList(float delta) {
        for(var i = chatList.Count - 1; i >= 0; --i) {
            var timerCounter = chatList[i].timeCounter - delta;
            if(timerCounter <= 0) {
                chatList.RemoveAt(i);
                RefreshChatUI();
            }
            else {
                chatList[i].timeCounter = timerCounter;
            }
        }
    }
    
    private void RefreshChatUI() {
        if(chatList.Count > 0) {
            SetActive(txtChat);
            var chatStr = chatList.Aggregate("", (current, t) => current + (t.chatMsg + "\n"));
            txtChat.text = chatStr;
        }
        else {
            SetActive(txtChat, false);
        }
    }

    /// <summary>
    /// PING
    /// </summary>
    /// <param name="time"></param>
    private void UpdatePing(int time)
    {
        txtDelay.text = time + "ms";
    }

    /// <summary>
    /// 设置复活
    /// </summary>
    /// <param name="isRevive"></param>
    /// <param name="reviveSec"></param>
    public void SetReviveTime(bool isRevive, int reviveSec)
    {
        if(isRevive) {
            if(blueTeamKillCount + redTeamKillCount != 1) {
                BattleController.Instance.PlayBattleFieldAudio("selfDeath");
            }
            SetActive(imgCover);
            
            var timer = new MonoTimer(reviveSec)
            {
                OnTimeUpdated = seconds =>
                {
                    SetText(txtRevieTime, $"复活时间{Mathf.CeilToInt(seconds)}秒");
                }
            };
            timer.Start();
            GameRoot.Instance.AddMonoTimer(timer);
        }
        else {
            SetActive(imgCover, false);
        }
    }

    /// <summary>
    /// 设置击杀
    /// </summary>
    /// <param name="killHeroTeam"></param>
    public void SetKillData(TeamEnum killHeroTeam) {
        if(killHeroTeam == TeamEnum.Blue) {
            ++blueTeamKillCount;
            SetText(txtBlueKill, blueTeamKillCount);
        }
        else {
            ++redTeamKillCount;
            SetText(txtRedKill, redTeamKillCount);
        }

        if(blueTeamKillCount + redTeamKillCount == 1) {
            BattleController.Instance.PlayBattleFieldAudio("firstblood");
        }
    }
    
    
    /// <summary>
    /// Time 显示层帧
    /// </summary>
    private void UpdateTime(float delta) {
        battleTimeCounter += delta;
        // 每秒执行一次
        if (!(battleTimeCounter >= 1)) return;
        ++battleSecondCount;
        battleTimeCounter -= 1;
        SetText(txtTime, Tool.ConvertSecondsToTime(battleSecondCount));
    }
    
    /// <summary>
    /// FPS 显示层帧
    /// </summary>
    /// <param name="delta"></param>
    private void UpdateFPS(float delta) {
        frameTimeCount += delta;
        ++frameCounter;
        // 每2秒执行一次
        if (!(frameTimeCount >= 2)) return;
        SetText(txtFPS, "FPS " + frameCounter / 2);
        frameTimeCount -= 2;
        frameCounter = 0;
    }
    
    
    /// <summary>
    /// coin 逻辑层
    /// </summary>
    /// <param name="income"></param>
    public void RefreshIncome(int income) {
        SetText(txtIncome, income);
    }
    
    #endregion
}
